package com.stoney.utils;


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;

import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.CharBuffer;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by Stony on 2015/11/24.
 */
public class FilesUtil {

    private final static  org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(FilesUtil.class);
    public static void print(String format,Object...agrs){
        logger.info(String.format(format,agrs));
    }

    public static final String DEFAULT_CHARSET = "utf-8";
    public static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

    public static void close(OutputStream s){
        try{
            if(s != null) s.close();
        }catch (IOException e){}
    }
    public static void close(InputStream s){
        try{
            if(s != null) s.close();
        }catch (IOException e){}
    }
    public static void close(Reader s){
        try{
            if(s != null) s.close();
        }catch (IOException e){}
    }
    public static void close(Writer s){
        try{
            if(s != null) s.close();
        }catch (IOException e){}
    }

    public static String getHtml(String url) {
        print("enter get Html <%s>",url);
        HttpClient httpclient;
        CookieStore cookieStore;
        HttpContext localContext;
        httpclient = new DefaultHttpClient();
        cookieStore = new BasicCookieStore();
        localContext = new BasicHttpContext();
        localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
        HttpGet httpget = new HttpGet(url);
        HttpResponse response;
        String html = "";
        try {
            int timeout = 80000;
            /** set client connection parameters **/
            httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
            httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);

            response = httpclient.execute(httpget, localContext);
            HttpEntity entity = response.getEntity();
            int statusCode = response.getStatusLine().getStatusCode();
            if ((statusCode == HttpStatus.SC_MOVED_PERMANENTLY) || (statusCode == HttpStatus.SC_MOVED_TEMPORARILY) ||
                    (statusCode == HttpStatus.SC_SEE_OTHER) || (statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
                String newUri = response.getLastHeader("Location").getValue();
                print("Location new url is %s.", newUri);
            }else{
                html = EntityUtils.toString(entity, DEFAULT_CHARSET);
            }
            EntityUtils.consume(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e){
            e.printStackTrace();
        }finally{
            close(httpclient);
        }
        return html;
    }
    public static String getFileHtml(String name){
        StringBuffer info = new StringBuffer();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(name)), DEFAULT_CHARSET));
            String line;
            while ((line = reader.readLine()) != null) {
                info.append(line);
//				System.out.println(line);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return info.toString();
    }

    public static void close(HttpClient httpclient){
        try{
            if(httpclient != null && httpclient.getConnectionManager() != null){
                httpclient.getConnectionManager().shutdown();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static void checkDir(String path){
        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
    }
    @Deprecated
    /**
     * @see #savePage(String, String)
     */
    public static boolean saveHtml(String url,String dir){
        int timeoutMillis = 20000;
        boolean flag = false;
        ParserUrl parser = new ParserUrl(url);
        File outFile = new File(parser.getOutFilePath(dir,".html"));
        BufferedWriter writer = null;
        if(isSaveFile(outFile)){
            checkDir(outFile.getParent());
            try {
                Document doc = Jsoup.connect(url).timeout(timeoutMillis).get();
                writer = new BufferedWriter(new FileWriter(outFile));
                writer.write(doc.html());
                writer.flush();
                flag = true;
            } catch (Exception e){
                flag = false;
                e.printStackTrace();
            } finally {
                close(writer);
            }
        }
        return flag;
    }
    private static AtomicInteger pindex = new AtomicInteger(0);
    public static boolean savePage(String url,String dir,String html){
        boolean flag = false;
        ParserUrl parser = new ParserUrl(url);
        File outFile = new File(parser.getOutFilePath(dir,".html"));
        BufferedWriter writer = null;
        if(isSaveFile(outFile)){
            checkDir(outFile.getParent());
            try {
                writer = new BufferedWriter(new FileWriter(outFile));
                writer.write(html);
                writer.flush();
                flag = true;
                pindex.incrementAndGet();
                print("[%d] Save Page <%s>|##|<%s> succeed.", pindex.get(), url, outFile.getAbsoluteFile());
            } catch (Exception e) {
                flag = false;
                print("[%d] Save Page <%s>|##|<%s> failed.", pindex.get(), url, outFile.getAbsoluteFile());
                e.printStackTrace();

            } finally {
                close(writer);
            }
        }
        return flag;
    }
    public static boolean savePage(String url,String dir) {
        boolean flag = true;
        ParserUrl parser = new ParserUrl(url);
        File outFile = new File(parser.getOutFilePath(dir,".html"));
        print("[%d] Save Page <%s>|##|<%s> enter.", pindex.get(), url, outFile.getAbsoluteFile());
        if (isSaveFile(outFile)) {
            checkDir(outFile.getParent());
            HttpURLConnection conn = null;
            BufferedReader reader = null;
            FileOutputStream out = null;
            try {
                conn = createGet(url);

                conn.connect();
                if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
                    out = new FileOutputStream(outFile);
                    int line;
                    while((line = reader.read()) != -1){
                        out.write(line);
                    }
                    out.flush();
                    pindex.incrementAndGet();
                    flag = true;
                    print("[%d] Save Page <%s>|##|<%s> succeed.", pindex.get(), url, outFile.getAbsoluteFile());
                }else{
                    print("[%d] Save Page <%s>|##|<%s> failed.", pindex.get(), url, outFile.getAbsoluteFile());
                    flag = false;
                }
            } catch (IOException e) {
                print("[%d] Save Page <%s>|##|<%s> failed.", pindex.get(), url, outFile.getAbsoluteFile());
                flag = false;
            }finally{
                close(reader);
                close(out);
                close(conn);
            }
        }
        return flag;
    }
    public static boolean savePage2(String url,String dir){
        boolean flag = false;
        ParserUrl parser = new ParserUrl(url);
        File outFile = new File(parser.getOutFilePath(dir,".html"));
        print("[%d] Save Page <%s>|##|<%s> enter.", pindex.get(), url, outFile.getAbsoluteFile());
        if(isSaveFile(outFile)){
            checkDir(outFile.getParent());
//            CloseableHttpClient httpClient = (CloseableHttpClient) createHttpClient();
            DefaultHttpClient httpClient = new DefaultHttpClient();
            try {
                HttpGet httpGet = new HttpGet(url);
                HttpResponse response = httpClient.execute(httpGet);
                flag = (save(response, outFile));
                pindex.incrementAndGet();
                print("[%d] Save Page <%s>|##|<%s> succeed.", pindex.get(), url, outFile.getAbsoluteFile());
            } catch (Exception e) {
                print("[%d] Save Page <%s>|##|<%s> failed.", pindex.get(), url, outFile.getAbsoluteFile());
                e.printStackTrace();
                flag = false;
            } finally {
                close(httpClient);
            }
        }
        return flag;
    }
    public static boolean save(HttpResponse response, File outfile) throws Exception {
        HttpEntity httpEntity = response.getEntity();
        boolean flag = false;
        if(response.getStatusLine().getStatusCode() == 200 && httpEntity != null) {
            BufferedReader reader = null;
            BufferedWriter writer = null;
            InputStream in = null;
            try {
                httpEntity = new BufferedHttpEntity(httpEntity);
                in = httpEntity.getContent();
                reader = new BufferedReader(new InputStreamReader(in, DEFAULT_CHARSET));
                writer = new BufferedWriter(new FileWriter(outfile));
                char buf[] = new char[DEFAULT_BUFFER_SIZE];
                while(reader.read(buf) != -1){
                    writer.write(buf);
                }
                writer.flush();
                flag = true;
            } catch (Exception e){
                flag = false;
                e.printStackTrace();
            } finally {
                close(reader);
                close(in);
                close(writer);
            }
        }
        return flag;
    }
    public static String extaUrl(String url){
        return url.substring(0,url.lastIndexOf("?"));
    }
    public static String extaImgeType(String img){
        return img.substring(img.lastIndexOf(".") + 1);
    }

    public static boolean isSaveFile(String file){
        return isSaveFile(new File(file));
    }
    public static boolean isSaveFile(File file){
        return !file.exists();
    }


    public static void initDir(String dirs){
        File dir = new File(dirs);
        if(!dir.exists()){
            dir.mkdirs();
        }
        if(dir.exists()){
            dir.canExecute();
            dir.canRead();
            dir.canWrite();
        }
    }

    public static boolean isEmpty(String str){
        return str == null || str.length() == 0;
    }
    public static boolean isNotEmpty(String str){
        return !isEmpty(str);
    }
    private static final int SOCKET_OPERATION_TIMEOUT = 60 * 1000;
    public static final HttpURLConnection createGet(String url) throws IOException {
        int timeout = SOCKET_OPERATION_TIMEOUT;
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setConnectTimeout(timeout);
        conn.setReadTimeout(timeout);
        conn.setRequestMethod("GET");
        conn.setUseCaches(false);
        conn.addRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36");
        return conn;
    }
    private static AtomicInteger cindex = new AtomicInteger(0);
    public static boolean saveResource(String url,String dir){
        ParserUrl parser = new ParserUrl(url);
        File outFile = new File(parser.getOutFilePath(dir));
        print("[%d] Save Media <%s>|##|<%s> enter.", cindex.get(), url, outFile.getAbsoluteFile());
        boolean flag = true;
        if(isSaveFile(outFile)) {
            checkDir(outFile.getParent());
            HttpURLConnection conn = null;
            InputStream in = null;
            FileOutputStream out = null;
            try {
                conn = createGet(url);
                conn.connect();
                if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    in = conn.getInputStream();
                    out = new FileOutputStream(outFile);
                    byte[] buffer = new byte[1024 * 4];
                    while(true){
                        int len = in.read(buffer);
                        if(len == -1){
                            break;
                        }
                        out.write(buffer, 0, len);
                    }
                    out.flush();
                    cindex.incrementAndGet();
                    flag = true;
                    print("[%d] Save Media <%s>|##|<%s> succeed.", cindex.get(), url, outFile.getAbsoluteFile());
                }else{
                    print("[%d] Save Media <%s>|##|<%s> failed.", cindex.get(), url, outFile.getAbsoluteFile());
                    flag = false;
                }
            } catch (IOException e) {
                print("[%d] Save Media <%s>|##|<%s> failed.", cindex.get(), url, outFile.getAbsoluteFile());
                flag = false;
            }finally{
                close(in);
                close(out);
                close(conn);
            }
        }
        return flag;
    }

    private static void close(HttpURLConnection conn) {
        if(conn != null) conn.disconnect();
    }

    public static boolean saveResource2(String url,String dir){
        ParserUrl parser = new ParserUrl(url);
        File outFile = new File(parser.getOutFilePath(dir));
        print("[%d] Save Media <%s>|##|<%s> enter.", cindex.get(), url, outFile.getAbsoluteFile());
        boolean flag = false;
        if(isSaveFile(outFile)){
            checkDir(outFile.getParent());
//            CloseableHttpClient httpClient = (CloseableHttpClient) createHttpClient();
            DefaultHttpClient httpClient = new DefaultHttpClient();
            try {
                HttpGet httpGet = new HttpGet(url);
                HttpResponse response = httpClient.execute(httpGet);
                flag = (save(response, outFile));
                cindex.incrementAndGet();
                print("[%d] Save Media <%s>|##|<%s> succeed.", cindex.get(), url, outFile.getAbsoluteFile());
            } catch (Exception e) {
                print("[%d] Save Media <%s>|##|<%s> failed.", cindex.get(), url, outFile.getAbsoluteFile());
                e.printStackTrace();
            } finally {
                close(httpClient);
            }
        }
        return flag;
    }



    public static void saveImg(String url,String dir) {
        print("save src : %s", url);
        String path = getImgPath(url);
        HttpClient httpclient = null;
        HttpContext localContext = null;
        //System.out.println("-------path :  " + path);
        try{
            if (isNotEmpty(path)) {
                File file = new File(dir + path);
                if (!file.exists())
                    file.mkdirs();
                String imgName = getImgName(url);
                HttpGet httpget = null;
                HttpResponse response;
                try {
                    File imageFile = new File(dir + path + "/" + imgName);
                    if (!imageFile.exists()) {

                    }
                    httpclient = new DefaultHttpClient();
                    localContext = new BasicHttpContext();

                    httpget = new HttpGet(url);
                    response = httpclient.execute(httpget, localContext);
                    HttpEntity entity = response.getEntity();

                    FileOutputStream outStream = new FileOutputStream(imageFile);
                    outStream.write(EntityUtils.toByteArray(entity));
                    outStream.close();
                    EntityUtils.consume(entity);
                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }finally {
            close(httpclient);
        }
    }
    static String getImgPath(String url) {
        //System.out.println("getImgPath : " + url);
        if (url.startsWith("http:")) {
            url = url.substring(url.indexOf("//") + 1);
            url = url.substring(url.indexOf("/") + 1);
            url = url.substring(0, url.lastIndexOf("/"));
            return url;
        } else {
            return null;
        }
    }

    static String getImgName(String url) {
        //System.out.println("getImgName : " + url);
        url = url.substring(url.lastIndexOf("/") + 1);
        if(url.lastIndexOf("?") != -1 ){
            url = url.substring(0, url.lastIndexOf("?"));
        }
        return url;
    }
}
